import json
import re

from re_common.baselibrary.tools.myparsel import MParsel
from re_common.baselibrary.utils.basedict import BaseDicts
from re_common.baselibrary.utils.baseencode import BaseEncode

from apps.core.callback import semicolon_call_back
from apps.crawler_platform.core_platform.core_g import CoreSqlValue
from apps.crawler_platform.core_platform.g_model import CallBackModel, OtherHomeModel, DealModel, DealInsertModel, \
    OtherListModel, OtherSubclassModel, OtherArticleModel

__all__ = ["baiduxueshu_baiduxuehome_callback",
           "baiduxueshu_baiduxuehomesearch_callback",
           "baiduxueshu_baiduxuelist_callback",
           "baiduxueshu_baiduxuename_callback",
           "baiduxueshu_baiduxuearticle_callback"
           ]


def baiduxueshu_baiduxuehome_callback(callmodel: CallBackModel[OtherHomeModel]) -> DealModel:
    result = DealModel()
    para_dicts = callmodel.para_dicts
    home_json = callmodel.sql_model.home_json
    home_json_dict = json.loads(home_json)
    # print(para_dicts)
    task_info = callmodel.redis_all.parse_dict["1_2"].task_info

    sql_model = callmodel.sql_model
    info_dicts = {"task_name": task_info.task_name,
                  "task_tag": task_info.task_tag,
                  "task_tag_next": task_info.task_tag_next,
                  "sub_db_id": sql_model.sub_db_id
                  }

    if "1_1" in para_dicts["data"]:
        html = para_dicts["data"]["1_1"]["html"]

        rule1 = re.compile(r'bds\.cf\.ts = \"(.*?)\";')
        rule2 = re.compile(r'bds\.cf\.token = \"(.*?)\";')
        rule3 = re.compile(r'md5\(ts \+  bds\.cf\.token \+ \'(.*?)\'\)')

        ts = rule1.findall(html)[0]
        token = rule2.findall(html)[0]
        # 生成sign的参数
        _sign = rule3.findall(html)[0]

        sign = BaseEncode.get_md5_value(
            ts + token + _sign)

        home_json_dict["ts"] = ts
        home_json_dict["token"] = token
        home_json_dict["_sign"] = _sign
        home_json_dict["sign"] = sign

    if "1_2" in para_dicts["data"]:
        html = para_dicts["data"]["1_2"]["htmldata"]
        if html.find("未检索到任何结果") > -1:
            pass
        else:
            rule4 = re.compile("data-num=\"(.*?)\"")
            pages = rule4.findall(html)
            pages = [r for r in pages if r != ""]
            if not pages:
                page = 1
                result.code_dicts = {
                    "1_2": {"max_page": 1}
                }
            else:
                pages = [int(i) if i.isdigit() else 0 for i in pages]
                page = max(pages)
                result.code_dicts = {
                    "1_2": {"max_page": page}
                }

            d_i_model = DealInsertModel()
            d_i_model.insert_pre = CoreSqlValue.insert_ig_it
            for i in range(1, int(page) + 1):
                temp = info_dicts.copy()
                temp["page"] = page
                temp["list_rawid"] = sql_model.list_rawid
                temp["page_index"] = i
                temp["home_json"] = json.dumps(home_json_dict, ensure_ascii=False)
                temp["is_active"] = 1
                temp["task_tag"] = temp["task_tag_next"]
                del temp["task_tag_next"]
                d_i_model.lists.append(temp)
            result.befor_dicts.insert.append(d_i_model)
    result.befor_dicts.update["home_json"] = json.dumps(home_json_dict, ensure_ascii=False)
    return result


def baiduxueshu_baiduxuehomesearch_callback(callmodel: CallBackModel[OtherHomeModel]) -> DealModel:
    result = DealModel()
    para_dicts = callmodel.para_dicts
    list_rawid = callmodel.sql_model.list_rawid
    task_info = callmodel.redis_all.parse_dict["1_1"].task_info
    info_dicts = {"task_name": task_info.task_name,
                  "task_tag": task_info.task_tag,
                  "sub_db_id": callmodel.sql_model.sub_db_id,
                  "task_tag_next": task_info.task_tag_next}
    html = para_dicts["data"]["1_1"]["htmldata"]

    xpath_rule = {
        "parent": '//div[contains(@class,"searchResultItem")]',
        "children":
            {
                "name": 'div[@class="searchResult_text"]/a[@class="personName"]/text()',
                "is_v": 'div[@class="searchResult_text"]/a[@class="personName"]/i/@class',
                "url": 'div[@class="searchResult_text"]/a[@class="personName"]/@href',
                "organ": 'div[@class="searchResult_text"]/p[contains(@class,"personInstitution")]/text()',
                "personNum": 'div[@class="searchResult_text"]/div[@class="personNum"]/p[@class="personNumItem"]//text()',
                "personField": 'div[@class="searchResult_text"]/p[@class="personField"]//text()'
            }
    }

    mc = MParsel(html=html)
    new_dict = mc.xpath_parsel(sel=mc.sel, xpath_selector=xpath_rule)
    BaseDicts.get_recursive_dict(new_dict, None, semicolon_call_back)

    dicts_temp = {}
    insert = DealInsertModel()
    insert.insert_pre = CoreSqlValue.insert_ig_it
    for item in new_dict["children"]:
        temp = info_dicts.copy()
        temp["task_tag"] = temp["task_tag_next"]
        del temp["task_tag_next"]

        dicts_temp["name"] = item["name"]
        if item["name"] == list_rawid:
            dicts_temp["is_same_name"] = "true"
        else:
            dicts_temp["is_same_name"] = "false"
        if item["is_v"] != "":
            dicts_temp["is_v"] = "true"
        else:
            dicts_temp["is_v"] = "false"
        url = item["url"]
        id_rawid = url.split("/")[-1]
        temp["list_rawid"] = list_rawid + "," + id_rawid
        dicts_temp["rawid"] = id_rawid
        dicts_temp["organ"] = item["organ"]
        _, article_Num, _, cite_num = item["personNum"].split(";")
        personField = item["personField"].split(";")[-1]

        dicts_temp["article_Num"], dicts_temp["cite_num"], dicts_temp[
            "personField"] = article_Num, cite_num, personField

        dicts_temp["home_list_rawid"] = list_rawid
        temp["list_json"] = json.dumps(dicts_temp, ensure_ascii=False)
        insert.lists.append(temp)

    result.next_dicts.insert.append(insert)

    return result


def baiduxueshu_baiduxuelist_callback(callmodel: CallBackModel[OtherListModel]) -> DealModel:
    result = DealModel()
    para_dicts = callmodel.para_dicts
    list_json = callmodel.sql_model.list_json

    task_info = callmodel.redis_all.parse_dict["1_1"].task_info

    sql_model = callmodel.sql_model
    info_dicts = {"task_name": task_info.task_name,
                  "task_tag": task_info.task_tag,
                  "task_tag_next": task_info.task_tag_next,
                  "sub_db_id": sql_model.sub_db_id
                  }

    # print(para_dicts)
    html = para_dicts["data"]["1_1"]["html"]
    xpath_rule = {
        "page_list": '//div[@class="res-pages-wr"]/p[@class="res-page"]/span/@data-num',
        "scholar_id": '//span[@class="p_scholarID_id"]/text()'
    }
    mc = MParsel(html=html)
    new_dict = mc.xpath_parsel(sel=mc.sel, xpath_selector=xpath_rule)
    BaseDicts.get_recursive_dict(new_dict, None, semicolon_call_back)
    # print(new_dict)
    scholar_id = new_dict["scholar_id"]
    pages = new_dict["page_list"].split(";")
    pages = [r for r in pages if r != ""]
    if not pages:
        page = 1
        result.code_dicts = {
            "1_1": {"max_page": 1}
        }
    else:
        pages = [int(i) if i.isdigit() else 0 for i in pages]
        page = max(pages)
        result.code_dicts = {
            "1_1": {"max_page": page}
        }

    rule1 = re.compile(r'bds\.cf\.ts = \"(.*?)\";')
    rule2 = re.compile(r'bds\.cf\.token = \"(.*?)\";')
    rule3 = re.compile(r'md5\(ts \+  bds\.cf\.token \+ \'(.*?)\'\)')
    rule4 = re.compile(r"entity_id: '(.*?)'")

    ts = rule1.findall(html)[0]
    token = rule2.findall(html)[0]
    # 生成sign的参数
    _sign = rule3.findall(html)[0]
    entity_id = rule4.findall(html)[0]

    sign = BaseEncode.get_md5_value(
        ts + token + _sign)

    list_json_dict = json.loads(list_json)
    list_json_dict["ts"] = ts
    list_json_dict["token"] = token
    list_json_dict["_sign"] = _sign
    list_json_dict["sign"] = sign
    list_json_dict["entity_id"] = entity_id
    list_json_dict["scholar_id"] = scholar_id
    list_json_dict["page"] = page

    d_i_model = DealInsertModel()
    d_i_model.insert_pre = CoreSqlValue.insert_ig_it
    for i in range(1, int(page) + 1):
        temp = info_dicts.copy()
        temp["page"] = page
        temp["list_rawid"] = scholar_id
        temp["page_index"] = i
        temp["subclass_json"] = json.dumps(list_json_dict, ensure_ascii=False)
        temp["is_active"] = 1
        temp["task_tag"] = temp["task_tag_next"]
        del temp["task_tag_next"]
        d_i_model.lists.append(temp)
    result.next_dicts.insert.append(d_i_model)

    result.befor_dicts.update = {"list_json": json.dumps(list_json_dict, ensure_ascii=False)}

    return result


def baiduxueshu_baiduxuename_callback(callmodel: CallBackModel[OtherSubclassModel]) -> DealModel:
    result = DealModel()
    para_dicts = callmodel.para_dicts
    # print(para_dicts)
    subclass_json = callmodel.sql_model.subclass_json

    task_info = callmodel.redis_all.parse_dict["1_1"].task_info

    sql_model = callmodel.sql_model
    info_dicts = {"task_name": task_info.task_name,
                  "task_tag": task_info.task_tag,
                  "task_tag_next": task_info.task_tag_next,
                  "sub_db_id": sql_model.sub_db_id
                  }

    d_i_model = DealInsertModel()
    d_i_model.insert_pre = CoreSqlValue.insert_ig_it
    subclass_json_dict = json.loads(subclass_json)
    for item in para_dicts["data"]["1_1"]["children"]:
        item["list_rawid"] = sql_model.list_rawid
        temp = info_dicts.copy()
        temp["rawid"] = item["articleid"]
        item["name"] = subclass_json_dict["name"]
        item["home_list_rawid"] = subclass_json_dict["home_list_rawid"]
        item["article_Num"] = subclass_json_dict["article_Num"]
        item["is_same_name"] = subclass_json_dict["is_same_name"]
        item["is_v"] = subclass_json_dict["is_v"]
        temp["article_info_json"] = json.dumps(item, ensure_ascii=False)
        temp["task_tag"] = temp["task_tag_next"]
        del temp["task_tag_next"]
        d_i_model.lists.append(temp)
    result.next_dicts.insert.append(d_i_model)

    return result


def baiduxueshu_baiduxuearticle_callback(callmodel: CallBackModel[OtherArticleModel]) -> DealModel:
    result = DealModel()



    return result
